﻿
using MCPlatform.Communicate.Modbus.Modbus;
using NModbus;
using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace MCPlatform.UI.Controls.Views
{
    /// <summary>
    /// ConnDebug.xaml 的交互逻辑
    /// </summary>
    public partial class ModbusTcpDebugView : Window
    {
        public TCPMaster Master { get; set; }

        //写线圈或写寄存器数组
        bool[]? coilsBuffer;
        ushort[]? registerBuffer;
        ushort startAddress;
        ushort numberOfPoints;
        string? functionCode = null;
        public ModbusTcpDebugView(TCPMaster master)
        {
            InitializeComponent();
            this.DataContext = this;
            Master = master;
        }

        private void readButton_Click(object sender, RoutedEventArgs e)
        {
          
            ExecuteFunction();
        }

        private void writeButton_Click(object sender, RoutedEventArgs e)
        {
            ExecuteFunction();
        }

        private async void ExecuteFunction()
        {
            if (!Master.IsConnected)
            {
                MessageBox.Show($"{Master.SlaveName}连接已断开");
                this.Close();
                return;
            }

            try
            {
                //重新实例化是为了 modbus slave更换连接时不报错 
                functionCode = functionComboBox.Text;
                if (functionCode != null)
                {
                    switch (functionCode)
                    {
                        case "01 Read Coils"://读取单个线圈
                            SetReadParameters();
                            coilsBuffer = await Master.ReadCoilsAsync(startAddress, numberOfPoints);

                            for (int i = 0; i < coilsBuffer?.Length; i++)
                            {
                                SetMsg(coilsBuffer[i] + " ");
                            }
                            SetMsg("\r\n");
                            break;
                        case "02 Read DisCrete Inputs"://读取输入线圈/离散量线圈
                            SetReadParameters();

                            coilsBuffer = Master.ReadInputs( startAddress, numberOfPoints);
                            for (int i = 0; i < coilsBuffer?.Length; i++)
                            {
                                SetMsg(coilsBuffer[i] + " ");
                            }
                            SetMsg("\r\n");
                            break;
                        case "03 Read Holding Registers"://读取保持寄存器
                            SetReadParameters();
                            if (this.comboBox.SelectedItem is null || this.comboBox is null || this.comboBox.SelectedItem.ToString() is null)
                            {
                                return;
                            }

                          

                            if (this.comboBox.SelectedItem.ToString().Contains("floatABCD"))
                            {
                                var floatdata = await Master.ReadHoldingRegistersWithFloatABCDAsync(startAddress, numberOfPoints);
                                foreach (var item in floatdata)
                                {
                                    SetMsg(item + " ");
                                }
                                SetMsg("\r\n");
                            }
                            else if (this.comboBox.SelectedItem.ToString().Contains("floatCDAB"))
                            {
                                var floatdata = await Master.ReadHoldingRegistersWithFloatAsync(startAddress, numberOfPoints);
                                foreach (var item in floatdata)
                                {
                                    SetMsg(item + " ");
                                }
                                SetMsg("\r\n");
                            }
                            else if (this.comboBox.SelectedItem.ToString().Contains("ushort"))
                            {
                                var ushortdata = await Master.ReadHoldingRegistersAsync(startAddress, numberOfPoints);

                                if (ushortdata is null)
                                {
                                    return;
                                }
                                foreach (var item in ushortdata)
                                {
                                    SetMsg(item + " ");
                                }
                                SetMsg("\r\n");
                            }
                            else if (this.comboBox.SelectedItem.ToString().Contains("string"))
                            {
                                var stringdata = await Master.ReadString(startAddress, numberOfPoints);


                                SetMsg(stringdata + "\r\n");


                            }
                            else if (this.comboBox.SelectedItem.ToString().Contains("int"))
                            {
                                var intdata = await Master.ReadSingleHoldingRegistersAsync(startAddress);


                                SetMsg(intdata + "\r\n");


                            }



                            break;

                        case "04 Read Input Registers"://读取输入寄存器
                            SetReadParameters();
                            registerBuffer = Master.ReadInputRegisters( startAddress, numberOfPoints);
                            for (int i = 0; i < registerBuffer.Length; i++)
                            {
                                SetMsg(registerBuffer[i] + " ");
                            }
                            SetMsg("\r\n");
                            break;
                        case "05 Write Single Coil"://写单个线圈
                            SetWriteParametes();
                             Master.WriteSingleCoilAsync(startAddress, coilsBuffer[0]);
                            break;
                        case "06 Write Single Registers"://写单个输入线圈/离散量线圈
                            SetWriteParametes();
                            //  Master.WriteSingleRegisterAsync( startAddress, registerBuffer[0]);
                            ushort[] singleRegisterBuffer = new ushort[2];
                            singleRegisterBuffer[0] = registerBuffer[0];
                            if (registerBuffer.Length>1)
                            {
                                singleRegisterBuffer[1] = registerBuffer[1];
                            }
                            
                            await Master.WriteMultipleRegistersAsync(startAddress, singleRegisterBuffer);
                            break;
                        case "0F Write Multiple Coils"://写一组线圈
                            SetWriteParametes();
                            await Master.WriteMultipleCoilsAsync( startAddress, coilsBuffer);
                            break;
                        case "10 Write Multiple Registers"://写一组保持寄存器
                            SetWriteParametes();
                            await Master.WriteMultipleRegistersAsync(startAddress, registerBuffer);
                            break;
                        case "11 Write string"://写字符串

                            SetWriteParametes();
                            if (this.comboBoxWrite.SelectedItem.ToString().Contains("Clear"))
                            {
                                await Master.ClearString(startAddress);
                            }
                            else
                            {
                                await Master.WriteString(startAddress, tb_data.Text);
                            }
                           
                            break;
                        case "12 Write int"://写整数

                            string[] strarr = tb_data.Text.Split(' ');
                            if (strarr.Length > 0)
                            {
                                short data = short.Parse(strarr[0]);
                                await Master.WriteSingleRegisterAsync(startAddress, data);
                            }

                            break;
                        default:
                            break;
                    }

                }
                else
                {
                    MessageBox.Show("请选择功能码!");
                }
               // Master.Dispose();
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 初始化读参数
        /// </summary>
        private void SetReadParameters()
        {
            if ((tb_startAddress.Text == ""  || tb_length.Text == ""))
            {
                MessageBox.Show("请填写读参数!");
            }
            else
            {
                
                startAddress = ushort.Parse(tb_startAddress.Text);
                numberOfPoints = ushort.Parse(tb_length.Text);
            }
        }

        /// <summary>
        /// 初始化写参数
        /// </summary>
        private void SetWriteParametes()
        {
            if ((tb_startAddress2.Text == ""  || tb_data.Text == "") && !this.comboBoxWrite.SelectedItem.ToString().Contains("Clear"))
            {
                MessageBox.Show("请填写写参数!");
            }
            else
            {
             
                startAddress = ushort.Parse(tb_startAddress2.Text);
                //判断是否写线圈
                if (functionComboBox.SelectedIndex == 4 || functionComboBox.SelectedIndex == 6)
                {
                    string[] strarr = tb_data.Text.Split(' ');
                    coilsBuffer = new bool[strarr.Length];
                    //转化为bool数组
                    for (int i = 0; i < strarr.Length; i++)
                    {
                        // strarr[i] == "0" ? coilsBuffer[i] = true : coilsBuffer[i] = false;
                        if (strarr[i] == "0")
                        {
                            coilsBuffer[i] = false;
                        }
                        else
                        {
                            coilsBuffer[i] = true;
                        }
                    }
                }
                else
                {
                    //转化ushort数组
                    string[] strarr = tb_data.Text.Split(' ');

                    List<ushort> writeData = new List<ushort>();

                    foreach (var item in strarr)
                    {
                        
                            ushort[] buff = new ushort[2];
                        if (this.comboBoxWrite.SelectedItem.ToString().Contains("floatABCD"))
                        {
                            TCPMaster.SetRealABCD(buff, 0, Single.Parse(item));
                            writeData.AddRange(buff);
                        }
                        else if (this.comboBoxWrite.SelectedItem.ToString().Contains("floatCDAB"))
                        {

                            TCPMaster.SetReal(buff, 0, Single.Parse(item));
                            writeData.AddRange(buff);
                        }
                        else
                        {
                            writeData.Add(ushort.Parse(item));
                        }
                        
                                             
                                        
                    }

                    registerBuffer = writeData.ToArray();

                    //registerBuffer = new ushort[strarr.Length];

                    //for (int i = 0; i < strarr.Length; i++)
                    //{
                    //    registerBuffer[i] = ushort.Parse(strarr[i]);
                    //}
                }
            }
        }
       

        public void SetMsg(string msg)
        {
            // richTextBox.Invoke(new Action(() => { richTextBox.AppendText(msg); }));
            richTextBox.AppendText(msg);
        }

        private void clearButton_Click(object sender, RoutedEventArgs e)
        {
            richTextBox.Document.Blocks.Clear();
        }

        private void functionComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

            if (functionComboBox.SelectedIndex >= 4)
            {
               
                //this.gb_read.IsEnabled = false;
                //this.gb_write.IsEnabled = true;
            }
            else
            {
               
                //this.gb_read.IsEnabled = true;
                //this.gb_write.IsEnabled = false;
            }
        }
    }
}
